package comm.suger.web.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName: StringHelper
 * @Description: 字符串工具类
 * @author Lanxiaowei
 * @date 2014-2-23 下午3:20:39
 */
@SuppressWarnings("deprecation")
public class StringHelper {
	private static final String HEXES = "0123456789ABCDEF";
	private static final String[] escapeIgnore = new String[] { "*", "+", "-", ".", "/", "@", "_" };
	private static final String[] encodeURIIgnore = new String[] { "!", "#", "$", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", ":", ";", "=", "?", "@", "_", "~" };
	private static final String[] encodeURIComponentIgnore = new String[] { "!", "'", "(", ")", "*", "-", ".", "_", "~" };

	private static char[] CODEC_TABLE = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e',
			'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };

	private static byte[] base64DecodeChars = new byte[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
			-1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
			19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 };

	private static Pattern metaPattern = Pattern.compile("<meta\\s+([^>]*http-equiv=\"?content-type\"?[^>]*)>", Pattern.CASE_INSENSITIVE);
	private static Pattern charsetPattern = Pattern.compile("charset=\\s*([a-z][_\\-0-9a-z]*)", Pattern.CASE_INSENSITIVE);

	/** HTML实体 */
	private static Map<String, Integer> htmlEntities = new HashMap<String, Integer>();
	static {
		htmlEntities.put("nbsp", new Integer(160));
		htmlEntities.put("iexcl", new Integer(161));
		htmlEntities.put("cent", new Integer(162));
		htmlEntities.put("pound", new Integer(163));
		htmlEntities.put("curren", new Integer(164));
		htmlEntities.put("yen", new Integer(165));
		htmlEntities.put("brvbar", new Integer(166));
		htmlEntities.put("sect", new Integer(167));
		htmlEntities.put("uml", new Integer(168));
		htmlEntities.put("copy", new Integer(169));
		htmlEntities.put("ordf", new Integer(170));
		htmlEntities.put("laquo", new Integer(171));
		htmlEntities.put("not", new Integer(172));
		htmlEntities.put("shy", new Integer(173));
		htmlEntities.put("reg", new Integer(174));
		htmlEntities.put("macr", new Integer(175));
		htmlEntities.put("deg", new Integer(176));
		htmlEntities.put("plusmn", new Integer(177));
		htmlEntities.put("sup2", new Integer(178));
		htmlEntities.put("sup3", new Integer(179));
		htmlEntities.put("acute", new Integer(180));
		htmlEntities.put("micro", new Integer(181));
		htmlEntities.put("para", new Integer(182));
		htmlEntities.put("middot", new Integer(183));
		htmlEntities.put("cedil", new Integer(184));
		htmlEntities.put("sup1", new Integer(185));
		htmlEntities.put("ordm", new Integer(186));
		htmlEntities.put("raquo", new Integer(187));
		htmlEntities.put("frac14", new Integer(188));
		htmlEntities.put("frac12", new Integer(189));
		htmlEntities.put("frac34", new Integer(190));
		htmlEntities.put("iquest", new Integer(191));
		htmlEntities.put("Agrave", new Integer(192));
		htmlEntities.put("Aacute", new Integer(193));
		htmlEntities.put("Acirc", new Integer(194));
		htmlEntities.put("Atilde", new Integer(195));
		htmlEntities.put("Auml", new Integer(196));
		htmlEntities.put("Aring", new Integer(197));
		htmlEntities.put("AElig", new Integer(198));
		htmlEntities.put("Ccedil", new Integer(199));
		htmlEntities.put("Egrave", new Integer(200));
		htmlEntities.put("Eacute", new Integer(201));
		htmlEntities.put("Ecirc", new Integer(202));
		htmlEntities.put("Euml", new Integer(203));
		htmlEntities.put("Igrave", new Integer(204));
		htmlEntities.put("Iacute", new Integer(205));
		htmlEntities.put("Icirc", new Integer(206));
		htmlEntities.put("Iuml", new Integer(207));
		htmlEntities.put("ETH", new Integer(208));
		htmlEntities.put("Ntilde", new Integer(209));
		htmlEntities.put("Ograve", new Integer(210));
		htmlEntities.put("Oacute", new Integer(211));
		htmlEntities.put("Ocirc", new Integer(212));
		htmlEntities.put("Otilde", new Integer(213));
		htmlEntities.put("Ouml", new Integer(214));
		htmlEntities.put("times", new Integer(215));
		htmlEntities.put("Oslash", new Integer(216));
		htmlEntities.put("Ugrave", new Integer(217));
		htmlEntities.put("Uacute", new Integer(218));
		htmlEntities.put("Ucirc", new Integer(219));
		htmlEntities.put("Uuml", new Integer(220));
		htmlEntities.put("Yacute", new Integer(221));
		htmlEntities.put("THORN", new Integer(222));
		htmlEntities.put("szlig", new Integer(223));
		htmlEntities.put("agrave", new Integer(224));
		htmlEntities.put("aacute", new Integer(225));
		htmlEntities.put("acirc", new Integer(226));
		htmlEntities.put("atilde", new Integer(227));
		htmlEntities.put("auml", new Integer(228));
		htmlEntities.put("aring", new Integer(229));
		htmlEntities.put("aelig", new Integer(230));
		htmlEntities.put("ccedil", new Integer(231));
		htmlEntities.put("egrave", new Integer(232));
		htmlEntities.put("eacute", new Integer(233));
		htmlEntities.put("ecirc", new Integer(234));
		htmlEntities.put("euml", new Integer(235));
		htmlEntities.put("igrave", new Integer(236));
		htmlEntities.put("iacute", new Integer(237));
		htmlEntities.put("icirc", new Integer(238));
		htmlEntities.put("iuml", new Integer(239));
		htmlEntities.put("eth", new Integer(240));
		htmlEntities.put("ntilde", new Integer(241));
		htmlEntities.put("ograve", new Integer(242));
		htmlEntities.put("oacute", new Integer(243));
		htmlEntities.put("ocirc", new Integer(244));
		htmlEntities.put("otilde", new Integer(245));
		htmlEntities.put("ouml", new Integer(246));
		htmlEntities.put("divide", new Integer(247));
		htmlEntities.put("oslash", new Integer(248));
		htmlEntities.put("ugrave", new Integer(249));
		htmlEntities.put("uacute", new Integer(250));
		htmlEntities.put("ucirc", new Integer(251));
		htmlEntities.put("uuml", new Integer(252));
		htmlEntities.put("yacute", new Integer(253));
		htmlEntities.put("thorn", new Integer(254));
		htmlEntities.put("yuml", new Integer(255));
		htmlEntities.put("fnof", new Integer(402));
		htmlEntities.put("Alpha", new Integer(913));
		htmlEntities.put("Beta", new Integer(914));
		htmlEntities.put("Gamma", new Integer(915));
		htmlEntities.put("Delta", new Integer(916));
		htmlEntities.put("Epsilon", new Integer(917));
		htmlEntities.put("Zeta", new Integer(918));
		htmlEntities.put("Eta", new Integer(919));
		htmlEntities.put("Theta", new Integer(920));
		htmlEntities.put("Iota", new Integer(921));
		htmlEntities.put("Kappa", new Integer(922));
		htmlEntities.put("Lambda", new Integer(923));
		htmlEntities.put("Mu", new Integer(924));
		htmlEntities.put("Nu", new Integer(925));
		htmlEntities.put("Xi", new Integer(926));
		htmlEntities.put("Omicron", new Integer(927));
		htmlEntities.put("Pi", new Integer(928));
		htmlEntities.put("Rho", new Integer(929));
		htmlEntities.put("Sigma", new Integer(931));
		htmlEntities.put("Tau", new Integer(932));
		htmlEntities.put("Upsilon", new Integer(933));
		htmlEntities.put("Phi", new Integer(934));
		htmlEntities.put("Chi", new Integer(935));
		htmlEntities.put("Psi", new Integer(936));
		htmlEntities.put("Omega", new Integer(937));
		htmlEntities.put("alpha", new Integer(945));
		htmlEntities.put("beta", new Integer(946));
		htmlEntities.put("gamma", new Integer(947));
		htmlEntities.put("delta", new Integer(948));
		htmlEntities.put("epsilon", new Integer(949));
		htmlEntities.put("zeta", new Integer(950));
		htmlEntities.put("eta", new Integer(951));
		htmlEntities.put("theta", new Integer(952));
		htmlEntities.put("iota", new Integer(953));
		htmlEntities.put("kappa", new Integer(954));
		htmlEntities.put("lambda", new Integer(955));
		htmlEntities.put("mu", new Integer(956));
		htmlEntities.put("nu", new Integer(957));
		htmlEntities.put("xi", new Integer(958));
		htmlEntities.put("omicron", new Integer(959));
		htmlEntities.put("pi", new Integer(960));
		htmlEntities.put("rho", new Integer(961));
		htmlEntities.put("sigmaf", new Integer(962));
		htmlEntities.put("sigma", new Integer(963));
		htmlEntities.put("tau", new Integer(964));
		htmlEntities.put("upsilon", new Integer(965));
		htmlEntities.put("phi", new Integer(966));
		htmlEntities.put("chi", new Integer(967));
		htmlEntities.put("psi", new Integer(968));
		htmlEntities.put("omega", new Integer(969));
		htmlEntities.put("thetasym", new Integer(977));
		htmlEntities.put("upsih", new Integer(978));
		htmlEntities.put("piv", new Integer(982));
		htmlEntities.put("bull", new Integer(8226));
		htmlEntities.put("hellip", new Integer(8230));
		htmlEntities.put("prime", new Integer(8242));
		htmlEntities.put("Prime", new Integer(8243));
		htmlEntities.put("oline", new Integer(8254));
		htmlEntities.put("frasl", new Integer(8260));
		htmlEntities.put("weierp", new Integer(8472));
		htmlEntities.put("image", new Integer(8465));
		htmlEntities.put("real", new Integer(8476));
		htmlEntities.put("trade", new Integer(8482));
		htmlEntities.put("alefsym", new Integer(8501));
		htmlEntities.put("larr", new Integer(8592));
		htmlEntities.put("uarr", new Integer(8593));
		htmlEntities.put("rarr", new Integer(8594));
		htmlEntities.put("darr", new Integer(8595));
		htmlEntities.put("harr", new Integer(8596));
		htmlEntities.put("crarr", new Integer(8629));
		htmlEntities.put("lArr", new Integer(8656));
		htmlEntities.put("uArr", new Integer(8657));
		htmlEntities.put("rArr", new Integer(8658));
		htmlEntities.put("dArr", new Integer(8659));
		htmlEntities.put("hArr", new Integer(8660));
		htmlEntities.put("forall", new Integer(8704));
		htmlEntities.put("part", new Integer(8706));
		htmlEntities.put("exist", new Integer(8707));
		htmlEntities.put("empty", new Integer(8709));
		htmlEntities.put("nabla", new Integer(8711));
		htmlEntities.put("isin", new Integer(8712));
		htmlEntities.put("notin", new Integer(8713));
		htmlEntities.put("ni", new Integer(8715));
		htmlEntities.put("prod", new Integer(8719));
		htmlEntities.put("sum", new Integer(8721));
		htmlEntities.put("minus", new Integer(8722));
		htmlEntities.put("lowast", new Integer(8727));
		htmlEntities.put("radic", new Integer(8730));
		htmlEntities.put("prop", new Integer(8733));
		htmlEntities.put("infin", new Integer(8734));
		htmlEntities.put("ang", new Integer(8736));
		htmlEntities.put("and", new Integer(8743));
		htmlEntities.put("or", new Integer(8744));
		htmlEntities.put("cap", new Integer(8745));
		htmlEntities.put("cup", new Integer(8746));
		htmlEntities.put("int", new Integer(8747));
		htmlEntities.put("there4", new Integer(8756));
		htmlEntities.put("sim", new Integer(8764));
		htmlEntities.put("cong", new Integer(8773));
		htmlEntities.put("asymp", new Integer(8776));
		htmlEntities.put("ne", new Integer(8800));
		htmlEntities.put("equiv", new Integer(8801));
		htmlEntities.put("le", new Integer(8804));
		htmlEntities.put("ge", new Integer(8805));
		htmlEntities.put("sub", new Integer(8834));
		htmlEntities.put("sup", new Integer(8835));
		htmlEntities.put("nsub", new Integer(8836));
		htmlEntities.put("sube", new Integer(8838));
		htmlEntities.put("supe", new Integer(8839));
		htmlEntities.put("oplus", new Integer(8853));
		htmlEntities.put("otimes", new Integer(8855));
		htmlEntities.put("perp", new Integer(8869));
		htmlEntities.put("sdot", new Integer(8901));
		htmlEntities.put("lceil", new Integer(8968));
		htmlEntities.put("rceil", new Integer(8969));
		htmlEntities.put("lfloor", new Integer(8970));
		htmlEntities.put("rfloor", new Integer(8971));
		htmlEntities.put("lang", new Integer(9001));
		htmlEntities.put("rang", new Integer(9002));
		htmlEntities.put("loz", new Integer(9674));
		htmlEntities.put("spades", new Integer(9824));
		htmlEntities.put("clubs", new Integer(9827));
		htmlEntities.put("hearts", new Integer(9829));
		htmlEntities.put("diams", new Integer(9830));
		htmlEntities.put("quot", new Integer(34));
		htmlEntities.put("amp", new Integer(38));
		htmlEntities.put("lt", new Integer(60));
		htmlEntities.put("gt", new Integer(62));
		htmlEntities.put("OElig", new Integer(338));
		htmlEntities.put("oelig", new Integer(339));
		htmlEntities.put("Scaron", new Integer(352));
		htmlEntities.put("scaron", new Integer(353));
		htmlEntities.put("Yuml", new Integer(376));
		htmlEntities.put("circ", new Integer(710));
		htmlEntities.put("tilde", new Integer(732));
		htmlEntities.put("ensp", new Integer(8194));
		htmlEntities.put("emsp", new Integer(8195));
		htmlEntities.put("thinsp", new Integer(8201));
		htmlEntities.put("zwnj", new Integer(8204));
		htmlEntities.put("zwj", new Integer(8205));
		htmlEntities.put("lrm", new Integer(8206));
		htmlEntities.put("rlm", new Integer(8207));
		htmlEntities.put("ndash", new Integer(8211));
		htmlEntities.put("mdash", new Integer(8212));
		htmlEntities.put("lsquo", new Integer(8216));
		htmlEntities.put("rsquo", new Integer(8217));
		htmlEntities.put("sbquo", new Integer(8218));
		htmlEntities.put("ldquo", new Integer(8220));
		htmlEntities.put("rdquo", new Integer(8221));
		htmlEntities.put("bdquo", new Integer(8222));
		htmlEntities.put("dagger", new Integer(8224));
		htmlEntities.put("Dagger", new Integer(8225));
		htmlEntities.put("permil", new Integer(8240));
		htmlEntities.put("lsaquo", new Integer(8249));
		htmlEntities.put("rsaquo", new Integer(8250));
		htmlEntities.put("euro", new Integer(8364));
	}

	/**
	 * 判断字符串为空(包含null和"")
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmptyString(String str) {
		return (null == str || "".equals(str));
	}

	/**
	 * 判断字符串非空
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNotEmptyString(String str) {
		return !isEmptyString(str);
	}

	/**
	 * @Title: replace
	 * @Description: 字符串替换[带缓冲区,比JDK自带的replace函数性能要高]
	 * @param strSrc
	 * @param strOld
	 * @param strNew
	 * @return
	 */
	public static final String replace(String strSrc, String strOld, String strNew) {
		if (strSrc == null || strOld == null || strNew == null) {
			return "";
		}
		int i = 0;

		if (strOld.equals(strNew)) {
			return strSrc;
		}
		if ((i = strSrc.indexOf(strOld, i)) >= 0) {
			char[] arr_cSrc = strSrc.toCharArray();
			char[] arr_cNew = strNew.toCharArray();

			int intOldLen = strOld.length();
			StringBuffer buf = new StringBuffer(arr_cSrc.length);
			buf.append(arr_cSrc, 0, i).append(arr_cNew);

			i += intOldLen;
			int j = i;

			while ((i = strSrc.indexOf(strOld, i)) > 0) {
				buf.append(arr_cSrc, j, i - j).append(arr_cNew);
				i += intOldLen;
				j = i;
			}

			buf.append(arr_cSrc, j, arr_cSrc.length - j);

			return buf.toString();
		}

		return strSrc;
	}

	/**
	 * @Title: escapeHTML
	 * @Description: 转义HTML代码
	 * @param s
	 * @return
	 */
	public static String escapeHTML(String s) {
		int length = s.length();
		int newLength = length;
		boolean someCharacterEscaped = false;
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			int cint = 0xffff & c;
			if (cint < 32) {
				switch (c) {
				case '\r':
				case '\n':
				case '\t':
				case '\f': {
				}
					break;
				default: {
					newLength -= 1;
					someCharacterEscaped = true;
				}
				}
			} else {
				switch (c) {
				case '\"': {
					newLength += 5;
					someCharacterEscaped = true;
				}
					break;
				case '&':
				case '\'': {
					newLength += 4;
					someCharacterEscaped = true;
				}
					break;
				case '<':
				case '>': {
					newLength += 3;
					someCharacterEscaped = true;
				}
					break;
				}
			}
		}
		if (!someCharacterEscaped) {
			return s;
		}
		StringBuffer sb = new StringBuffer(newLength);
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			int cint = 0xffff & c;
			if (cint < 32) {
				switch (c) {
				case '\r':
				case '\n':
				case '\t':
				case '\f': {
					sb.append(c);
				}
					break;
				default: {
					// Remove this character
				}
				}
			} else {
				switch (c) {
				case '\"': {
					sb.append("&quot;");
				}
					break;
				case '\'': {
					sb.append("&#39;");
				}
					break;
				case '&': {
					sb.append("&amp;");
				}
					break;
				case '<': {
					sb.append("&lt;");
				}
					break;
				case '>': {
					sb.append("&gt;");
				}
					break;
				default: {
					sb.append(c);
				}
				}
			}
		}
		return sb.toString();
	}

	/**
	 * @Title: escapeSQL
	 * @Description: 转义SQL语句
	 * @param s
	 * @return
	 */
	public static String escapeSQL(String s) {
		int length = s.length();
		int newLength = length;
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			switch (c) {
			case '\\':
			case '\"':
			case '\'':
			case '\0': {
				newLength += 1;
			}
				break;
			}
		}
		if (length == newLength) {
			return s;
		}
		StringBuffer sb = new StringBuffer(newLength);
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			switch (c) {
			case '\\': {
				sb.append("\\\\");
			}
				break;
			case '\"': {
				sb.append("\\\"");
			}
				break;
			case '\'': {
				sb.append("\\\'");
			}
				break;
			case '\0': {
				sb.append("\\0");
			}
				break;
			default: {
				sb.append(c);
			}
			}
		}
		return sb.toString();
	}

	/**
	 * @Title: escapeJavaCode
	 * @Description: 转义Java代码
	 * @param s
	 * @return
	 */
	public static String escapeJavaCode(String s) {
		int length = s.length();
		int newLength = length;
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			switch (c) {
			case '\"':
			case '\'':
			case '\n':
			case '\r':
			case '\t':
			case '\\': {
				newLength += 1;
			}
				break;
			}
		}
		if (length == newLength) {
			return s;
		}
		StringBuffer sb = new StringBuffer(newLength);
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			switch (c) {
			case '\"': {
				sb.append("\\\"");
			}
				break;
			case '\'': {
				sb.append("\\\'");
			}
				break;
			case '\n': {
				sb.append("\\n");
			}
				break;
			case '\r': {
				sb.append("\\r");
			}
				break;
			case '\t': {
				sb.append("\\t");
			}
				break;
			case '\\': {
				sb.append("\\\\");
			}
				break;
			default: {
				sb.append(c);
			}
			}
		}
		return sb.toString();
	}

	/**
	 * @Title: escapeRegularExpressionLiteral
	 * @Description: 转义正则表达式
	 * @param s
	 * @return
	 */
	public static String escapeRegularExpression(String s) {
		int length = s.length();
		int newLength = length;
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
				newLength += 1;
			}
		}
		if (length == newLength) {
			return s;
		}
		StringBuffer sb = new StringBuffer(newLength);
		for (int i = 0; i < length; i++) {
			char c = s.charAt(i);
			if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
				sb.append('\\');
			}
			sb.append(c);
		}
		return sb.toString();
	}

	/**
	 * @Title: unescapeHTML
	 * @Description: 反转义HTML
	 * @param s
	 * @return
	 */
	public static String unescapeHTML(String s) {
		StringBuffer result = new StringBuffer(s.length());
		int ampInd = s.indexOf("&");
		int lastEnd = 0;
		while (ampInd >= 0) {
			int nextAmp = s.indexOf("&", ampInd + 1);
			int nextSemi = s.indexOf(";", ampInd + 1);
			if (nextSemi != -1 && (nextAmp == -1 || nextSemi < nextAmp)) {
				int value = -1;
				String escape = s.substring(ampInd + 1, nextSemi);
				try {
					if (escape.startsWith("#")) {
						value = Integer.parseInt(escape.substring(1), 10);
					} else {
						if (htmlEntities.containsKey(escape)) {
							value = ((Integer) (htmlEntities.get(escape))).intValue();
						}
					}
				} catch (NumberFormatException x) {
				}
				result.append(s.substring(lastEnd, ampInd));
				lastEnd = nextSemi + 1;
				if (value >= 0 && value <= 0xffff) {
					result.append((char) value);
				} else {
					result.append("&").append(escape).append(";");
				}
			}
			ampInd = nextAmp;
		}
		result.append(s.substring(lastEnd));
		return result.toString();
	}

	/**
	 * @Title: encode
	 * @Description: BASE64编码( JDK自带的BASE64Encoder会有每76个字符末尾添加\r\n换行,此方法不会换行,
	 *               且BASE64Encoder编码性能极低,建议使用common-codec提供的BASE64编码函数或者使用此方法)
	 * @param @param str 传入需要BASE64编码的原字符串
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String base64Encode(String str) {
		byte[] bt = str.getBytes();
		int totalBits = bt.length * 8;
		int nn = totalBits % 6;
		int curPos = 0;
		StringBuffer toReturn = new StringBuffer();
		while (curPos < totalBits) {
			int bytePos = curPos / 8;
			switch (curPos % 8) {
			case 0:
				toReturn.append(CODEC_TABLE[(bt[bytePos] & 0xfc) >> 2]);
				break;
			case 2:
				toReturn.append(CODEC_TABLE[(bt[bytePos] & 0x3f)]);
				break;
			case 4:
				if (bytePos == bt.length - 1) {
					toReturn.append(CODEC_TABLE[((bt[bytePos] & 0x0f) << 2) & 0x3f]);
				} else {
					int pos = (((bt[bytePos] & 0x0f) << 2) | ((bt[bytePos + 1] & 0xc0) >> 6)) & 0x3f;
					toReturn.append(CODEC_TABLE[pos]);
				}
				break;
			case 6:
				if (bytePos == bt.length - 1) {
					toReturn.append(CODEC_TABLE[((bt[bytePos] & 0x03) << 4) & 0x3f]);
				} else {
					int pos = (((bt[bytePos] & 0x03) << 4) | ((bt[bytePos + 1] & 0xf0) >> 4)) & 0x3f;
					toReturn.append(CODEC_TABLE[pos]);
				}
				break;
			default:
				break;
			}
			curPos += 6;
		}
		if (nn == 2) {
			toReturn.append("==");
		} else if (nn == 4) {
			toReturn.append("=");
		}
		return toReturn.toString();
	}

	/**
	 * @Title: base64Decode
	 * @Description: BASE64解码
	 * @param @param str 传入需要进行BASE64解码的原字符串
	 * @param @return
	 * @param @throws UnsupportedEncodingException
	 * @return byte[]
	 * @throws
	 */
	public static byte[] base64Decode(String str) throws UnsupportedEncodingException {
		StringBuffer buffer = new StringBuffer();
		byte[] data = str.getBytes("US-ASCII");
		int len = data.length;
		int i = 0;
		int b1, b2, b3, b4;
		while (i < len) {
			/* b1 */
			do {
				b1 = base64DecodeChars[data[i++]];
			} while (i < len && b1 == -1);
			if (b1 == -1)
				break;
			/* b2 */
			do {
				b2 = base64DecodeChars[data[i++]];
			} while (i < len && b2 == -1);
			if (b2 == -1)
				break;
			buffer.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4)));
			/* b3 */
			do {
				b3 = data[i++];
				if (b3 == 61)
					return buffer.toString().getBytes("ISO-8859-1");
				b3 = base64DecodeChars[b3];
			} while (i < len && b3 == -1);
			if (b3 == -1)
				break;
			buffer.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));
			/* b4 */
			do {
				b4 = data[i++];
				if (b4 == 61)
					return buffer.toString().getBytes("ISO-8859-1");
				b4 = base64DecodeChars[b4];
			} while (i < len && b4 == -1);
			if (b4 == -1)
				break;
			buffer.append((char) (((b3 & 0x03) << 6) | b4));
		}
		return buffer.toString().getBytes("ISO-8859-1");
	}

	/**
	 * @Title: toHexString
	 * @Description: 字符串进行十六进制的ASCII编码
	 * @param @param s
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String toHexString(String s) {
		String str = "";
		for (int i = 0; i < s.length(); i++) {
			int ch = (int) s.charAt(i);
			String s4 = Integer.toHexString(ch);
			str = str + s4;
		}
		return str;
	}

	/**
	 * @Title: encode
	 * @Description: URL编码(原理:将字符转换成16进制,然后前面加前缀%,对于0-255范围之外字符加前缀%u)
	 *               不编码字符包括.-*_,注意空格会被编码成加号+,本函数已修复此BUG
	 * @param @param url
	 * @return void
	 * @throws
	 */
	public static String encode(String url) {
		if (isEmptyString(url)) {
			return url;
		}
		String result = URLEncoder.encode(url);
		result = result.replace("%3A", ":").replace("%2F", "/");
		result = result.replace("%3F", "?").replace("%3D", "=").replace("%26", "&");
		return result.replace("+", "%20");
	}

	/**
	 * @Title: decode
	 * @Description: URL解码(会将+加号解码成空格)
	 * @param @param url
	 * @return void
	 * @throws
	 */
	public static String decode(String url) {
		if (isEmptyString(url)) {
			return url;
		}
		return URLDecoder.decode(url);
	}

	/**
	 * @Title: escape
	 * @Description: URL中特殊字符编码(* + - . / @ _ 0-9 a-z A-Z不会被编码)
	 * @param @param src
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String escape(String src) {
		if (isEmptyString(src)) {
			return src;
		}
		char j = 0;
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length() * 6);
		for (int i = 0; i < src.length(); i++) {
			j = src.charAt(i);
			boolean flag = false;
			for (int k = 0; k < escapeIgnore.length; k++) {
				if (escapeIgnore[k].charAt(0) == j) {
					tmp.append(j);
					flag = true;
					break;
				}
			}
			if (!flag) {
				if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j)) {
					tmp.append(j);
				} else if (j < 256) {
					tmp.append("%");
					if (j < 16) {
						tmp.append("0");
					}
					tmp.append(Integer.toString(j, 16));
				} else {
					tmp.append("%u");
					tmp.append(Integer.toString(j, 16));
				}
			}
		}
		return tmp.toString();
	}

	/**
	 * @Title: encodeURI
	 * @Description: 对URI进行完整的编码(!#$&'()*+,-./:;=?@_~0-9a-zA-Z不会被编码)
	 * @param @param uriString
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String encodeURI(String src) {
		if (isEmptyString(src)) {
			return src;
		}
		char j = 0;
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length() * 6);
		for (int i = 0; i < src.length(); i++) {
			j = src.charAt(i);
			boolean flag = false;
			for (int k = 0; k < encodeURIIgnore.length; k++) {
				if (encodeURIIgnore[k].charAt(0) == j) {
					tmp.append(j);
					flag = true;
					break;
				}
			}
			if (!flag) {
				if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j)) {
					tmp.append(j);
				} else if (j < 256) {
					tmp.append("%");
					if (j < 16) {
						tmp.append("0");
					}
					tmp.append(Integer.toString(j, 16));
				} else {
					tmp.append("%u");
					tmp.append(Integer.toString(j, 16));
				}
			}
		}
		return tmp.toString();
	}

	/**
	 * @Title: encodeURIComponent
	 * @Description: 对URI参数部分进行编码(!'()*-._~0-9a-zA-Z不会被编码)
	 *               主要适用于对URL传递的特殊字符或中文参数部分进行编码,而不是把整个URL传递给此函数
	 *               eg:http://xxxx.do?qu=中文&r=50%,明显参数:中文和50%需要编码,
	 *               因此你只需要把中文和50%传递给此函数进行编码
	 * @param @param uriString
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String encodeURIComponent(String src) {
		if (isEmptyString(src)) {
			return src;
		}
		char j = 0;
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length() * 6);
		for (int i = 0; i < src.length(); i++) {
			j = src.charAt(i);
			boolean flag = false;
			for (int k = 0; k < encodeURIComponentIgnore.length; k++) {
				if (encodeURIComponentIgnore[k].charAt(0) == j) {
					tmp.append(j);
					flag = true;
					break;
				}
			}
			if (!flag) {
				if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j)) {
					tmp.append(j);
				} else if (j < 256) {
					tmp.append("%");
					if (j < 16) {
						tmp.append("0");
					}
					tmp.append(Integer.toString(j, 16));
				} else {
					tmp.append("%u");
					tmp.append(Integer.toString(j, 16));
				}
			}
		}
		return tmp.toString();
	}

	/**
	 * @Title: unescape
	 * @Description: URL中特殊字符解码，与escape功能相反
	 * @param @param src
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String unescape(String src) {
		StringBuffer tmp = new StringBuffer();
		tmp.ensureCapacity(src.length());
		int lastPos = 0, pos = 0;
		char ch;
		while (lastPos < src.length()) {
			pos = src.indexOf("%", lastPos);
			if (pos == lastPos) {
				if (src.charAt(pos + 1) == 'u') {
					ch = (char) Integer.parseInt(src.substring(pos + 2, pos + 6), 16);
					tmp.append(ch);
					lastPos = pos + 6;
				} else {
					ch = (char) Integer.parseInt(src.substring(pos + 1, pos + 3), 16);
					tmp.append(ch);
					lastPos = pos + 3;
				}
			} else {
				if (-1 == pos) {
					tmp.append(src.substring(lastPos));
					lastPos = src.length();
				} else {
					tmp.append(src.substring(lastPos, pos));
					lastPos = pos;
				}
			}
		}
		return tmp.toString();
	}

	/**
	 * 从字符串文本中提取日期字符串,如：xxxxxxx2/14/2013xxxxxxxx -->2/14/2013
	 * 
	 * @param text
	 * @return
	 */
	public static String getDateTextFromString(String text) {
		if (isEmptyString(text)) {
			return null;
		}
		StringBuffer reg = new StringBuffer();
		reg.append("((1|2)\\d{3})(/|-|.)(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9]) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("([12][0-9]|3[01]|0?[1-9])(/|-|.)(1[012]|0?[1-9])(/|-|.)((1|2)\\d{3}) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9])(/|-|.)((1|2)\\d{3}) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("((1|2)\\d{3})(/|-|.)(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9]) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("((1|2)\\d{3})(/|-|.)([12][0-9]|3[01]|0?[1-9])(/|-|.)(1[012]|0?[1-9]) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9]):([1-5][0-9]|0?[0-9])|");

		reg.append("((1|2)\\d{3})(/|-|.)(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9]) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("([12][0-9]|3[01]|0?[1-9])(/|-|.)(1[012]|0?[1-9])(/|-|.)((1|2)\\d{3}) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9])(/|-|.)((1|2)\\d{3}) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("((1|2)\\d{3})(/|-|.)(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9]) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("((1|2)\\d{3})(/|-|.)([12][0-9]|3[01]|0?[1-9])(/|-|.)(1[012]|0?[1-9]) (1[0-9]|2[0123]|0?[0-9]):([1-5][0-9]|0?[0-9])|");
		reg.append("((1|2)\\d{3})(/|-|.)(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9])|");
		reg.append("([12][0-9]|3[01]|0?[1-9])(/|-|.)(1[012]|0?[1-9])(/|-|.)((1|2)\\d{3})|");
		reg.append("(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9])(/|-|.)((1|2)\\d{3})|");
		reg.append("((1|2)\\d{3})(/|-|.)(1[012]|0?[1-9])(/|-|.)([12][0-9]|3[01]|0?[1-9])|");
		reg.append("((1|2)\\d{3})(/|-|.)([12][0-9]|3[01]|0?[1-9])(/|-|.)(1[012]|0?[1-9])");
		Pattern pattern = Pattern.compile(reg.toString());
		Matcher matcher = pattern.matcher(text);
		if (matcher.find()) {
			return matcher.group();
		}
		return null;
	}

	/**
	 * @Title: getDateTimeFromString
	 * @Description: 从字符串文本中提取日期时间字符串
	 * @param @param text
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String getDateTimeFromString(String text) {
		StringBuffer reg = new StringBuffer();
		reg.append("((1|2)\\d{3})(/|-|.)(0?[1-9]|1[012])(/|-|.)(0?[1-9]|[12][0-9]|3[01]) (0?[0-9]|1[0-9]|2[0123]):(0?[0-9]|[1-5][0-9]):(0?[0-9]|[1-5][0-9])$");
		Pattern pattern = Pattern.compile(reg.toString());
		Matcher matcher = pattern.matcher(text);
		if (matcher.find()) {
			return matcher.group();
		}
		return null;
	}

	/**
	 * 从字符串中提取出数字(可以提取整数和小数)
	 * 
	 * @param text
	 * @return
	 */
	public static String getNumbericFromString(String text) {
		if (isEmptyString(text)) {
			return null;
		}
		StringBuffer reg = new StringBuffer();
		reg.append("0\\.\\d+|[1-9]{1}([0-9]+)?\\.\\d+|\\d+");
		Pattern pattern = Pattern.compile(reg.toString());
		Matcher matcher = pattern.matcher(text);
		if (matcher.find()) {
			return matcher.group();
		}
		return null;
	}

	/**
	 * 从字符串中提取URL链接,<br/>
	 * 如:http://www.google.com.hk
	 * http://www.savings.com/popup/detail/coupon-723379.html
	 * 
	 * @param text
	 * @return
	 */
	public static String getURLFromString(String text) {
		if (isEmptyString(text)) {
			return null;
		}
		StringBuffer reg = new StringBuffer();
		reg.append("\\b((ftp|http|https?)://[-\\w]+(\\.\\w[-\\w]*)+|(?i:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\\.)+");
		reg.append("(?-i:com\\b|edu\\b|biz\\b|gov\\b|in(?:t|fo)\\b|mil\\b|net\\b|org\\b|[a-z][a-z]\\b))");
		reg.append("(:\\d+)?(/[^.!,?;\"'<>()\\[\\]{}\\s\\x7F-\\xFF]*(?:[.!,?]+[^.!,?;\"'<>()\\[\\]{}\\s\\x7F-\\xFF]+)*)?");
		Pattern pattern = Pattern.compile(reg.toString());
		Matcher matcher = pattern.matcher(text);
		if (matcher.find()) {
			return matcher.group();
		}
		return null;
	}

	/**
	 * 将毫秒转换成多少小时分钟秒的格式 如：12410000-->3小时26分钟50秒
	 * 
	 * @param time
	 * @return 格式化后的时间格式
	 * 
	 */
	public static String formatMillSecond(long time, String hourPlaceholder, String minuePlaceholder, String secondPlaceholder) {
		int hour = 0;
		int minute = 0;
		int second = 0;
		second = new Long(time).intValue() / 1000;
		if (second > 60) {
			minute = second / 60;
			second = second % 60;
		}
		if (minute > 60) {
			hour = minute / 60;
			minute = minute % 60;
		}
		StringBuffer buffer = new StringBuffer();
		if (hour > 0) {
			buffer.append(String.valueOf(hour)).append(hourPlaceholder);
		}
		if (minute > 0) {
			buffer.append(String.valueOf(minute)).append(minuePlaceholder);
		}
		if (second >= 0) {
			buffer.append(String.valueOf(second)).append(secondPlaceholder);
		}
		return buffer.toString();
	}

	/**
	 * 将多少小时分钟秒的格式字符串转换成毫秒数(与formatMillSecond方法相反) 如：3小时26分钟50秒-->12410000
	 * 
	 * @param str
	 * @return
	 */
	public static long unFormatMillSecond(String str) {
		if (isEmptyString(str)) {
			return 0;
		}
		Pattern pattern = Pattern.compile("\\d+");
		Matcher matcher = pattern.matcher(str);
		List<String> list = new ArrayList<String>();
		while (matcher.find()) {
			list.add(matcher.group());
		}
		if (list.size() != 3) {
			return 0;
		}
		int hour = Integer.parseInt(list.get(0));
		int minue = Integer.parseInt(list.get(1));
		int second = Integer.parseInt(list.get(2));
		return hour * 3600000 + minue * 60000 + second * 1000;
	}

	/**
	 * @Title: cleanComment
	 * @Description: 剔除JS/HTML注释
	 * @param @param str
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String cleanComment(String str) {
		if (isEmptyString(str)) {
			return null;
		}
		// 剔除此类注释：<!-- 这里是注释 -->
		Pattern pattern = Pattern.compile("<!--[\\w\\W\r\\n]*?-->");
		Matcher matcher = pattern.matcher(str);
		str = matcher.replaceAll("");
		// 剔除此类注释：/**这里是注释 */
		pattern = Pattern.compile("/\\*[\\w\\W\r\\n]*?\\*/");
		matcher = pattern.matcher(str);
		str = matcher.replaceAll("");
		// 剔除此类注释：//这里是注释
		str = str.replaceAll("//[^\n]*\n", "");
		return str;
	}

	/**
	 * @Title: cleanJavaScript
	 * @Description: 剔除所有的JavaScript代码 对于<script></script>标签之间含有</script>字符串的情况，
	 *               可能会有BUG，后续再完善 上述BUG已修复，支持<script>标签嵌套
	 * @param @param str
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String cleanJavaScript(String str) {
		/*
		 * if (isEmptyString(str)) { return null; } return
		 * str.replaceAll("(?s)<script.*?>(.*?)</script>","");
		 */
		if (isEmptyString(str)) {
			return null;
		}
		str = str.toLowerCase().replaceAll("<script(?:[^<]++|<(?!/script>))*+</script>", "<script>");
		while (str.contains("</script>")) {
			str = str.replaceAll("<script(?:[^<]++|<(?!/script>))*+</script>", "");
		}
		return str;
	}

	/**
	 * @Title: cleanCSS
	 * @Description: 剔除<style></style>标签之间的所有CSS代码
	 * @param @param str
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String cleanCSS(String str) {
		if (isEmptyString(str)) {
			return null;
		}
		return str.toLowerCase().replaceAll("(?s)<style.*?>(.*?)</style>", "");
	}

	/**
	 * Unicode字符串转换成中文
	 * 
	 * @param dataStr
	 * @return
	 */
	public static String decodeUnicode(final String dataStr) {
		int start = 0;
		int end = 0;
		final StringBuffer buffer = new StringBuffer();
		while (start > -1) {
			end = dataStr.indexOf("\\\\u", start + 2);
			String charStr = "";
			if (end == -1) {
				charStr = dataStr.substring(start + 2, dataStr.length());
			} else {
				charStr = dataStr.substring(start + 2, end);
			}
			char letter = (char) Integer.parseInt(charStr, 16);
			buffer.append(new Character(letter).toString());
			start = end;
		}
		return buffer.toString();
	}

	/**
	 * 判断字符串是否以数字结尾
	 * 
	 * @param str
	 * @return
	 */
	public static boolean endsWithNum(String str) {
		if (isEmptyString(str)) {
			return false;
		}
		String temp = str.replaceAll("\\d{1}$", "");
		return temp.length() != str.length();
	}

	/**
	 * 查找字符串中第一个大写字母的索引位置
	 * 
	 * @param str
	 * @return
	 */
	public static int findFirstUpperWordIndex(String str) {
		if (isEmptyString(str)) {
			return -1;
		}
		for (int i = 0; i < str.length(); i++) {
			char c = str.charAt(i);
			if (Character.isUpperCase(c)) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 剔除字符串结尾多余的换行符 如：I like java.\n\n\n\n --> I like java.
	 * 
	 * @param str
	 * @return
	 */
	public static String removeBreakLineOfEnd(String str) {
		if (isEmptyString(str)) {
			return null;
		}
		return str.replaceAll("([^\n]*)\n+$", "$1");
	}

	/**
	 * 将返回的JSON数据组装成一个HTML代码字符串
	 * 
	 * @param data
	 *            HTML代码片段
	 * @param pageTitle
	 *            HTML页面的title名称
	 * @param template
	 *            HTML模版
	 * @return
	 */
	public static String gernerateHTML(String data, String pageTitle, String template) {
		if (isEmptyString(data) || isEmptyString(template)) {
			return "";
		}
		if (isEmptyString(pageTitle)) {
			pageTitle = "New Page";
		}
		return String.format(template, data, pageTitle);
	}

	/**
	 * 从网页meta标签中提取出页面编码，<br/>
	 * 若页面未指定，默认返回null
	 * 
	 * @param html
	 * @return
	 */
	public static String getCharsetFromMeta(String html) {
		html = html.replace("contenexType", "content-type");
		html = html.replace("charseexType", "charset").replace("Content-Type", "content-type");
		Matcher metaMatcher = metaPattern.matcher(html);
		String encoding = null;
		if (metaMatcher.find()) {
			Matcher charsetMatcher = charsetPattern.matcher(metaMatcher.group(1));
			if (charsetMatcher.find()) {
				encoding = new String(charsetMatcher.group(1));
			}
		}
		return encoding;
	}

	/**
	 * 替换HTML页面meta部分声明的charset编码
	 * 
	 * @param html
	 *            html页面内容
	 * @param targetCharset
	 *            目标编码
	 * @return
	 */
	public static String replaceHTMLCharsetFromMeta(String html, String targetCharset) {
		if (isEmptyString(html)) {
			return null;
		}
		if (isEmptyString(targetCharset)) {
			return html;
		}
		Pattern pattern = Pattern.compile("<meta\\s+http-equiv=\"Content-Type\"\\s+content=\"[\\s\\S]*?charset=(\\S+?)\"\\s*/>");
		Matcher matcher = pattern.matcher(html);
		if (matcher.find()) {
			String meta = matcher.group();
			String oldCharset = matcher.group(1);
			String newMeta = meta.replace(oldCharset, targetCharset);
			html = html.replace(meta, newMeta);
		}
		return html;
	}

	/**
	 * @Title: md5
	 * @Description: 生成MD5摘要
	 * @param @param inStr
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String md5(String inStr) {
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
		char[] charArray = inStr.toCharArray();
		byte[] byteArray = new byte[charArray.length];
		for (int i = 0; i < charArray.length; i++) {
			byteArray[i] = (byte) charArray[i];
		}
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16) {
				hexValue.append("0");
			}
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}

	/**
	 * 字节数组转换成十六进制字符串
	 * 
	 * @param bytes
	 * @return
	 */
	public static String bytes2Hex(byte[] bytes) {
		if (bytes == null) {
			return null;
		}
		StringBuilder hex = new StringBuilder(2 * bytes.length);
		for (final byte b : bytes) {
			hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
		}
		return hex.toString();
	}

	/**
	 * 字符串转换成十六进制字符串
	 * 
	 * @param String
	 *            str 待转换的ASCII字符串
	 * @return String 每个Byte之间空格分隔，如: [61 6C 6B]
	 */
	public static String str2HexStr(String str) {
		char[] chars = "0123456789ABCDEF".toCharArray();
		StringBuilder sb = new StringBuilder("");
		byte[] bs = str.getBytes();
		int bit = 0;
		for (int i = 0; i < bs.length; i++) {
			bit = (bs[i] & 0x0f0) >> 4;
			sb.append(chars[bit]);
			bit = bs[i] & 0x0f;
			sb.append(chars[bit]);
			sb.append(' ');
		}
		return sb.toString().trim();
	}

	/**
	 * 十六进制转换字符串
	 * 
	 * @param String
	 *            str Byte字符串(Byte之间无分隔符 如:[616C6B])
	 * @return String 对应的字符串
	 */
	public static String hexStr2Str(String hexStr) {
		String str = "0123456789ABCDEF";
		char[] hexs = hexStr.toCharArray();
		byte[] bytes = new byte[hexStr.length() / 2];
		int n = 0;
		for (int i = 0; i < bytes.length; i++) {
			n = str.indexOf(hexs[2 * i]) * 16;
			n += str.indexOf(hexs[2 * i + 1]);
			bytes[i] = (byte) (n & 0xff);
		}
		return new String(bytes);
	}

	/**
	 * 字节数组转换成十六进制字符串
	 * 
	 * @param byte[] b byte数组
	 * @return String 每个Byte值之间空格分隔
	 */
	public static String byte2HexStr(byte[] b) {
		String stmp = "";
		StringBuilder sb = new StringBuilder("");
		for (int n = 0; n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0xFF);
			sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
			sb.append(" ");
		}
		return sb.toString().toUpperCase().trim();
	}

	/**
	 * bytes字符串转换为字节数组
	 * 
	 * @param String
	 *            src Byte字符串，每个Byte之间没有分隔符
	 * @return byte[]
	 */
	public static byte[] hexStr2Bytes(String src) {
		int m = 0, n = 0;
		int l = src.length() / 2;
		byte[] ret = new byte[l];
		for (int i = 0; i < l; i++) {
			m = i * 2 + 1;
			n = m + 1;
			ret[i] = Byte.decode("0x" + src.substring(i * 2, m) + src.substring(m, n));
		}
		return ret;
	}

	/**
	 * String的字符串转换成unicode的String
	 * 
	 * @param String
	 *            strText 全角字符串
	 * @return String 每个unicode之间无分隔符
	 * @throws Exception
	 */
	public static String strToUnicode(String strText) {
		char c;
		StringBuilder str = new StringBuilder();
		int intAsc = 0;
		String strHex = null;
		for (int i = 0; i < strText.length(); i++) {
			c = strText.charAt(i);
			intAsc = (int) c;
			strHex = Integer.toHexString(intAsc);
			if (intAsc > 128) {
				str.append("\\u" + strHex);
			} else { // 低位在前面补00
				str.append("\\u00" + strHex);
			}
		}
		return str.toString();
	}

	/**
	 * unicode的String转换成String的字符串
	 * 
	 * @param String
	 *            hex 16进制值字符串 （一个unicode为2byte）
	 * @return String 全角字符串
	 */
	public static String unicodeToString(String hex) {
		int t = hex.length() / 6;
		StringBuilder str = new StringBuilder();
		for (int i = 0; i < t; i++) {
			String s = hex.substring(i * 6, (i + 1) * 6);
			// 高位需要补上00再转
			String s1 = s.substring(2, 4) + "00";
			// 低位直接转
			String s2 = s.substring(4);
			// 将16进制的string转为int
			int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
			// 将int转换为字符
			char[] chars = Character.toChars(n);
			str.append(new String(chars));
		}
		return str.toString();
	}

	/**
	 * @Title: string2Unicode
	 * @Description: 字符串转换成Unicode编码形式
	 * @param @param str
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String string2Unicode(String str, String encoding) {
		try {
			str = new String(str.getBytes("ISO-8859-1"), encoding);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		char[] utfBytes = str.toCharArray();
		String unicodeBytes = "";
		for (int byteIndex = 0; byteIndex < utfBytes.length; byteIndex++) {
			String hexB = Integer.toHexString(utfBytes[byteIndex]);
			if (hexB.length() <= 2) {
				hexB = "00" + hexB;
			}
			unicodeBytes = unicodeBytes + "\\u" + hexB;
		}
		return unicodeBytes;
	}

	/**
	 * @Title: enUnicode
	 * @Description: 字符串Unicode编码
	 * @param @param s
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String enUnicode(String s) {
		StringBuilder sb = new StringBuilder(s.length() * 3);
		for (char c : s.toCharArray()) {
			if (c < 256) {
				sb.append(c);
			} else {
				sb.append("\\u");
				sb.append(Character.forDigit((c >>> 12) & 0xf, 16));
				sb.append(Character.forDigit((c >>> 8) & 0xf, 16));
				sb.append(Character.forDigit((c >>> 4) & 0xf, 16));
				sb.append(Character.forDigit((c) & 0xf, 16));
			}
		}
		return sb.toString();
	}

	/**
	 * @Title: unicode2String
	 * @Description: Unicode编码字符串还原成String
	 * @param @param unicodeStr
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String unicode2String(String str) {
		str = (str == null ? "" : str);
		if (str.indexOf("\\u") == -1) {
			return str;
		}
		StringBuffer buffer = new StringBuffer(1000);
		for (int i = 0; i < str.length() - 6;) {
			String strTemp = str.substring(i, i + 6);
			String value = strTemp.substring(2);
			int c = 0;
			for (int j = 0; j < value.length(); j++) {
				char tempChar = value.charAt(j);
				int t = 0;
				switch (tempChar) {
				case 'a':
					t = 10;
					break;
				case 'b':
					t = 11;
					break;
				case 'c':
					t = 12;
					break;
				case 'd':
					t = 13;
					break;
				case 'e':
					t = 14;
					break;
				case 'f':
					t = 15;
					break;
				default:
					t = tempChar - 48;
					break;
				}
				c += t * ((int) Math.pow(16, (value.length() - j - 1)));
			}
			buffer.append((char) c);
			i = i + 6;
		}
		return buffer.toString();
	}

	/**
	 * 判断是否为中文字符
	 * 
	 * @param c
	 * @return
	 */
	public static boolean isChinese(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
				|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
			return true;
		}
		return false;
	}

	/**
	 * @Title: isMessyCode
	 * @Description: 判断是否乱码
	 * @param @param strName
	 * @param @return
	 * @return boolean
	 * @throws
	 */
	public static boolean isMessyCode(String strName) {
		Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
		Matcher m = p.matcher(strName);
		String after = m.replaceAll("");
		String temp = after.replaceAll("\\p{P}", "");
		char[] ch = temp.trim().toCharArray();
		float chLength = ch.length;
		float count = 0;
		for (int i = 0; i < ch.length; i++) {
			char c = ch[i];
			if (!Character.isLetterOrDigit(c)) {
				if (!isChinese(c)) {
					count = count + 1;
				}
			}
		}
		float result = count / chLength;
		if (result > 0.20008) {
			return true;
		}
		return false;
	}

	/**
	 * @Title: reverseString
	 * @Description: 逗号分割的字符倒序排列
	 * @param @param str
	 * @param @return
	 * @return String
	 * @throws
	
	public static String reverseString(String str, String split) {
		if (!str.endsWith(",")) {
			str += ",";
		}
		String[] arrayData = str.split(split);
		List<String> list = Arrays.asList(arrayData);
		Collections.reverse(list);
		return GerneralUtils.joinCollection(list).replace("\",{", "\"},{") + "}";
	} */

	/**
	 * 全角字符转换成半角字符
	 * 
	 * @param source
	 * @return
	 */
	public static String convertStringToNarrow(String source) {
		StringBuffer result = new StringBuffer();
		char[] ch = source.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			if (ch[i] == 12288) {
				result.append(' ');
			} else if (ch[i] == 12290) {
				result.append('.');
			} else if (ch[i] >= 65281 && ch[i] <= 65374) {
				result.append((char) (ch[i] - 65248));
			} else {
				result.append(ch[i]);
			}
		}
		return result.toString();
	}

	/**
	 * 半角字符转换全角字符
	 * 
	 * @param source
	 * @return
	 */
	public static String convertStringToWide(String source) {
		StringBuffer result = new StringBuffer();
		char[] ch = source.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			if (ch[i] == 32) {
				result.append('　');
			} else if (ch[i] == 46) {
				result.append('。');
			} else if (ch[i] >= 33 && ch[i] <= 126) {
				result.append((char) (ch[i] + 65248));
			} else {
				result.append(ch[i]);
			}
		}
		return result.toString();
	}

	/**
	 * 字符串首字母转换成大写
	 * 
	 * @param text
	 * @return
	 */
	public static String upperFirstLetter(String text) {
		if (StringHelper.isEmptyString(text)) {
			return text;
		}
		String first = Character.toString(text.charAt(0)).toUpperCase();
		return new StringBuilder(text.length()).append(first).append(text.substring(1)).toString();
	}

	/**
	 * 字符串首字母转换成小写
	 * 
	 * @param text
	 * @return
	 */
	public static String lowerFirstLetter(String text) {
		if (StringHelper.isEmptyString(text)) {
			return text;
		}
		String first = Character.toString(text.charAt(0)).toLowerCase();
		return new StringBuilder(text.length()).append(first).append(text.substring(1)).toString();
	}

	/**
	 * 从get/set方法名中提取出属性名称
	 * 
	 * @return
	 */
	public static String getPropertyNameFromGetSet(String methodName) {
		if (null == methodName) {
			return null;
		}
		if (methodName.length() <= 3 || (!methodName.startsWith("get") && !methodName.startsWith("set"))) {
			return methodName;
		}
		return lowerFirstLetter(methodName.substring(3));
	}

	/**
	 * 骆驼命名法转换成数据库字段命名法，如studentName-->student_name
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param prefix
	 *            添加前缀
	 * @param stuffix
	 *            添加后缀
	 * @return
	 */
	public static String splitCamelName(String propertyName, String prefix, String stuffix) {
		if (StringHelper.isEmptyString(propertyName)) {
			return propertyName;
		}
		char[] dest = new char[propertyName.length()];
		propertyName.getChars(0, propertyName.length(), dest, 0);
		StringBuilder builder = new StringBuilder();
		if (StringHelper.isNotEmptyString(prefix)) {
			builder.append(prefix).append("_");
		}
		for (int i = 0; i < dest.length; i++) {
			if (i == 0) {
				builder.append(Character.toLowerCase(dest[i]));
				continue;
			}
			if (Character.isUpperCase(dest[i])) {
				builder.append("_").append(Character.toLowerCase(dest[i]));
			} else {
				builder.append(dest[i]);
			}
		}
		if (StringHelper.isNotEmptyString(stuffix)) {
			builder.append("_").append(stuffix);
		}
		return builder.toString();
	}

	/**
	 * 骆驼命名法转换成数据库字段命名法(重载)，如studentName-->student_name
	 * 
	 * @param propertyName
	 *            属性名称
	 * @return
	 */
	public static String splitCamelName(String propertyName) {
		return splitCamelName(propertyName, null, null);
	}

	/**
	 * 数据库字段名称转换成类属性名，如stu_name-->stuName
	 * 
	 * @param fieldName
	 *            数据库字段名称
	 * @param prefix
	 *            前缀
	 * @param stuffix
	 *            后缀
	 * @return
	 */
	public static String splitDBFieldName(String fieldName, String prefix, String stuffix) {
		if (StringHelper.isEmptyString(fieldName)) {
			return fieldName;
		}
		if (StringHelper.isNotEmptyString(prefix)) {
			if (prefix.endsWith("_")) {
				fieldName = fieldName.replaceAll("^" + prefix + "(.*)", "$1");
			} else {
				fieldName = fieldName.replaceAll("^" + prefix + "_(.*)", "$1");
			}
		} else {
			fieldName = fieldName.replaceAll("^_(.*)", "$1");
		}
		if (StringHelper.isNotEmptyString(stuffix)) {
			if (stuffix.startsWith("_")) {
				fieldName = fieldName.replaceAll("(.*)" + stuffix + "$", "$1");
			} else {
				fieldName = fieldName.replaceAll("(.*)_" + stuffix + "$", "$1");
			}
		} else {
			fieldName = fieldName.replaceAll("(.*)_$", "$1");
		}
		if (fieldName.indexOf("_") == -1) {
			return fieldName;
		}
		String[] array = fieldName.split("_");
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < array.length; i++) {
			if (i == 0) {
				builder.append(array[i].toLowerCase());
			} else {
				builder.append(upperFirstLetter(array[i]));
			}
		}
		return builder.toString();
	}

	/**
	 * 数据库字段名称转换成类属性名(重载)，如stu_name-->stuName
	 * 
	 * @param fieldName
	 *            数据库字段名称
	 * @return
	 */
	public static String splitDBFieldName(String fieldName) {
		return splitDBFieldName(fieldName, null, null);
	}

	/**
	 * 剔除结尾字符(如最后一个换行符、最后一个逗号等等)
	 * 
	 * @param str
	 *            待处理字符串
	 * @param regular
	 *            正则表达式
	 * @return 返回剔除后的字符
	 */
	public static String replaceEndsWith(String str, String regular) {
		if (StringHelper.isEmptyString(str)) {
			return null;
		}
		if (StringHelper.isEmptyString(regular)) {
			return str;
		}
		return str.replaceAll(regular, "");
	}

	private static final int SESSION_ID_BYTES = 16;

	private static MessageDigest getDigest() {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			return md;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @Title: generateSessionId
	 * @Description: 生成随机的SessionId
	 * @param @return
	 * @return String
	 * @throws
	 */
	public static String generateSessionId() {
		Random random = new SecureRandom(); // 取随机数发生器, 默认是SecureRandom
		byte bytes[] = new byte[SESSION_ID_BYTES];
		random.nextBytes(bytes); // 产生16字节的byte
		bytes = getDigest().digest(bytes); // 取摘要,默认是"MD5"算法
		StringBuffer result = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) { // 转化为16进制字符串
			byte b1 = (byte) ((bytes[i] & 0xf0) >> 4);
			byte b2 = (byte) (bytes[i] & 0x0f);
			if (b1 < 10) {
				result.append((char) ('0' + b1));
			} else {
				result.append((char) ('A' + (b1 - 10)));
			}
			if (b2 < 10) {
				result.append((char) ('0' + b2));
			} else {
				result.append((char) ('A' + (b2 - 10)));
			}
		}
		return (result.toString());
	}

	/**
	 * GBK to UTF-8
	 * 
	 * @param chenese
	 * @return
	 */
	public static String gbk2utf8(String gbk) {
		char c[] = gbk.toCharArray();
		byte[] fullByte = new byte[3 * c.length];
		for (int i = 0; i < c.length; i++) {
			int m = (int) c[i];
			String word = Integer.toBinaryString(m);

			StringBuffer sb = new StringBuffer();
			int len = 16 - word.length();
			// 补零
			for (int j = 0; j < len; j++) {
				sb.append("0");
			}
			sb.append(word);
			sb.insert(0, "1110");
			sb.insert(8, "10");
			sb.insert(16, "10");
			String s1 = sb.substring(0, 8);
			String s2 = sb.substring(8, 16);
			String s3 = sb.substring(16);

			byte b0 = Integer.valueOf(s1, 2).byteValue();
			byte b1 = Integer.valueOf(s2, 2).byteValue();
			byte b2 = Integer.valueOf(s3, 2).byteValue();
			byte[] bf = new byte[3];
			bf[0] = b0;
			fullByte[i * 3] = bf[0];
			bf[1] = b1;
			fullByte[i * 3 + 1] = bf[1];
			bf[2] = b2;
			fullByte[i * 3 + 2] = bf[2];
		}
		try {
			return new String(fullByte, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}
	
	 /**
     * String型变量转换成int型变量
     * @param str 要进行转换的字符串
     * @return intVal 如果str不可以转换成int型数据，返回-1表示异常,否则返回转换后的值
     * @since  1.0
     */
    public static int str2Int(String str) {
        int intVal;
        try {
            intVal = Integer.parseInt(str);
        } catch (Exception e) {
            intVal = 0;
        }
        return intVal;
    }

    public static double str2Double(String str) {
        double dVal = 0;
        try {
            dVal = Double.parseDouble(str);
        } catch (Exception e) {
            dVal = 0;
        }
        return dVal;
    }

    public static long str2Long(String str) {
        long longVal = 0;
        try {
            longVal = Long.parseLong(str);
        } catch (Exception e) {
            longVal = 0;
        }
        return longVal;
    }

    public static float stringToFloat(String floatstr) {
        Float floatee;
        floatee = Float.valueOf(floatstr);
        return floatee.floatValue();
    }

    public static String floatToString(float value) {
        Float floatee = new Float(value);
        return floatee.toString();
    }
    
    /**
     *int型变量转换成String型变量
     *@param intVal 要进行转换的整数
     *@return str 如果intVal不可以转换成String型数据，返回空值表示异常,否则返回转换后的值
     */
    /**
     *int型变量转换成String型变量
     *@param intVal 要进行转换的整数
     *@return str 如果intVal不可以转换成String型数据，返回空值表示异常,否则返回转换后的值
     */
    public static String int2Str(int intVal) {
        String str;
        try {
            str = String.valueOf(intVal);
        } catch (Exception e) {
            str = "";
        }
        return str;
    }

    /**
     *long型变量转换成String型变量
     *@param longVal 要进行转换的整数
     *@return str 如果longVal不可以转换成String型数据，返回空值表示异常,否则返回转换后的值
     */

    public static String long2Str(long longVal) {
        String str;
        try {
            str = String.valueOf(longVal);
        } catch (Exception e) {
            str = "";
        }
        return str;
    }

    /**
     *null 处理
     *@param str 要进行转换的字符串
     *@return 如果str为null值，返回空串"",否则返回str
     */
    public static String null2Blank(String str) {
        if (str == null) {
            return "";
        }
        return str;
    }

    /**
     *null 处理
     *@param d 要进行转换的日期对像
     *@return 如果d为null值，返回空串"",否则返回d.toString()
     */

    public static String null2Blank(Date d) {
        if (d == null) {
            return "";
        }
        return d.toString();
    }

    /**
     *null 处理
     *@param str 要进行转换的字符串
     *@return 如果str为null值，返回空串整数0,否则返回相应的整数
     */
    public static int null2Zero(String str) {
        int intTmp;
        intTmp = str2Int(str);
        if (intTmp == -1) {
            return 0;
        }
        return intTmp;
    }
    /**
     * 把null转换为字符串"0"
     * @param str
     * @return
     */
    public static String null2SZero(String str) {
        str = null2Blank(str);
        if (str.equals("")) {
            return "0";
        }
        return str;
    }
}
